package pzl.mn.practice.okhttp;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.BufferedSink;
import pzl.mn.practice.R;

public class OkhttpActivity extends AppCompatActivity {
    final String TAG = "jinx_okhttp";
    TextView tvmsg;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_okhttp);
        tvmsg = findViewById(R.id.tvMsg);
    }


    public void click(final View view) {
        tvmsg.setText("");
        switch (view.getId()) {
            case R.id.btnAsynGet:
                asynGet(view);
                break;
            case R.id.btnSynGet:
                synGet(view);
                break;
            case R.id.btnPostString:
                postString(view);
                break;
            case R.id.btnPostStream:
                postStream(view);
                break;
            case R.id.btnPostFile:
                postFile(view);
                break;
            case R.id.btnPostForm:
                postForm(view);
                break;
            case R.id.btnPostMultipartBody:
                postMultipartBody(view);
                break;
            case R.id.btnInterceptorLog:
                interceptor_Log(view);
                break;
        }
    }


    /**
     * interceptor
     * interceptor_Log
     *
     * @param view
     */
    private void interceptor_Log(final View view) {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(new LoggingInterceptor())
                .build();
        Request request = new Request.Builder()
                .url("http://www.publicobject.com/helloworld.txt")
                .header("User-Agent", "OkHttp Example")
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "onFailure: " + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                final String result = response.body().string();
                Log.d(TAG, "onResponse: " + result);
                view.post(new Runnable() {
                    @Override
                    public void run() {
                        tvmsg.append(result + '\n');
                    }
                });

            }
        });

    }

    /**
     * POST方式提交分块请求
     * MultipartBody 可以构建复杂的请求体，与HTML文件上传形式兼容。多块请求体中每块请求都是一个请求体，可以定义自己的请求头。
     *
     * @param view
     */
    private static final String IMGUR_CLIENT_ID = "...";
    private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");

    private void postMultipartBody(final View view) {
        OkHttpClient client = new OkHttpClient();
        // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image
        MultipartBody body = new MultipartBody.Builder("AaB03x")
                .setType(MultipartBody.FORM)
                .addPart(
                        Headers.of("Content-Disposition", "form-data; name=\"title\""),
                        RequestBody.create(null, "Square Logo"))
                .addPart(
                        Headers.of("Content-Disposition", "form-data; name=\"image\""),
                        RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))
                .build();

        Request request = new Request.Builder()
                .header("Authorization", "Client-ID " + IMGUR_CLIENT_ID)
                .url("https://api.imgur.com/3/image")
                .post(body)
                .build();

        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                final String result = response.body().string();
                System.out.println(result);
                view.post(new Runnable() {
                    @Override
                    public void run() {
                        tvmsg.append(result + '\n');
                    }
                });
            }
        });
    }


    /**
     * post 提交表单
     *
     * @param view
     */
    private void postForm(final View view) {
        OkHttpClient okHttpClient = new OkHttpClient();
        RequestBody requestBody = new FormBody.Builder()
                .add("search", "明星大侦探")
                .build();
        Request request = new Request.Builder()
                .url("https://en.wikipedia.org/w/index.php")
                .post(requestBody)
                .build();

        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "onFailure: " + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.d(TAG, response.protocol() + " " + response.code() + " " + response.message());
                Headers headers = response.headers();
                for (int i = 0; i < headers.size(); i++) {
                    Log.d(TAG, headers.name(i) + ":" + headers.value(i));
                }
                final String result = response.body().string();
                Log.d(TAG, "onResponse: " + result);
                view.post(new Runnable() {
                    @Override
                    public void run() {
                        tvmsg.append(result + '\n');
                    }
                });
            }
        });
    }

    /**
     * post 提交 文件
     *
     * @param view
     */
    private void postFile(final View view) {
        trans("test_file.txt");
        MediaType mediaType = MediaType.parse("text/x-markdown; charset=utf-8");
        OkHttpClient okHttpClient = new OkHttpClient();
        File file = new File(getFilesDir().getAbsolutePath() + File.separator + "test_file.txt");
        Request request = new Request.Builder()
                .url("https://api.github.com/markdown/raw")
                .post(RequestBody.create(mediaType, file))
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "onFailure: " + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.d(TAG, response.protocol() + " " + response.code() + " " + response.message());
                Headers headers = response.headers();
                for (int i = 0; i < headers.size(); i++) {
                    Log.d(TAG, headers.name(i) + ":" + headers.value(i));
                }
                final String result = response.body().string();
                Log.d(TAG, "onResponse: " + result);
                view.post(new Runnable() {
                    @Override
                    public void run() {
                        tvmsg.append(result + '\n');
                    }
                });
            }
        });
    }


    /**
     * postStream
     * post 方式发送流
     *
     * @param view
     */
    private void postStream(final View view) {
        RequestBody requestBody = new RequestBody() {
            @Nullable
            @Override
            public MediaType contentType() {
                return MediaType.parse("text/x-markdown; charset=utf-8");
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {
                sink.writeUtf8("I am Jdqm.");
            }
        };

        Request request = new Request.Builder()
                .url("https://api.github.com/markdown/raw")
                .post(requestBody)
                .build();
        OkHttpClient okHttpClient = new OkHttpClient();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "onFailure: " + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.d(TAG, response.protocol() + " " + response.code() + " " + response.message());
                Headers headers = response.headers();
                for (int i = 0; i < headers.size(); i++) {
                    Log.d(TAG, headers.name(i) + ":" + headers.value(i));
                }
                final String result = response.body().string();
                Log.d(TAG, "onResponse: " + result);
                view.post(new Runnable() {
                    @Override
                    public void run() {
                        tvmsg.append(result + '\n');
                    }
                });
            }
        });
    }

    /**
     * postStream String
     *
     * @param view
     */
    private void postString(final View view) {
        MediaType mediaType = MediaType.parse("text/x-markdown; charset=utf-8");
        String requestBody = "I am Jdqm.";
        Request request = new Request.Builder()
                .url("https://api.github.com/markdown/raw")
                .post(RequestBody.create(mediaType, requestBody))
                .build();
        OkHttpClient okHttpClient = new OkHttpClient();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "onFailure: " + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.d(TAG, response.protocol() + " " + response.code() + " " + response.message());
                Headers headers = response.headers();
                for (int i = 0; i < headers.size(); i++) {
                    Log.d(TAG, headers.name(i) + ":" + headers.value(i));
                }
                final String result = response.body().string();
                Log.d(TAG, "onResponse: " + result);
                view.post(new Runnable() {
                    @Override
                    public void run() {
                        tvmsg.append(result + '\n');
                    }
                });
            }
        });
    }


    /**
     * 同步get
     *
     * @param view
     */
    private void synGet(final View view) {
        String url = "http://wwww.baidu.com";
        OkHttpClient okHttpClient = new OkHttpClient();
        final Request request = new Request.Builder()
                .url(url)
                .build();
        final Call call = okHttpClient.newCall(request);
        new Thread(new Runnable() {
            @Override
            public void run() {
                String result = null;
                try {
                    Response response = call.execute();
                    result = response.body().string();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                final String finalResult = result;
                view.post(new Runnable() {
                    @Override
                    public void run() {
                        tvmsg.append(finalResult + '\n');
                    }
                });
            }
        }).start();
    }

    /**
     * 异步get
     *
     * @param view
     */
    private void asynGet(final View view) {
        String url = "https://api.github.com/";
        OkHttpClient okHttpClient = new OkHttpClient();
        final Request request = new Request.Builder()
                .url(url)
                .get()
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                tvmsg.append(e.getMessage() + '\n');
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                final String result = response.body().string();
                Log.i("jinx", result + "\n thread = " + Thread.currentThread().getName());
                view.post(new Runnable() {
                    @Override
                    public void run() {
                        tvmsg.append(result + '\n');
                    }
                });

            }
        });
    }

    private void trans(String fileName) {
        InputStream is = null;
        FileOutputStream fos = null;
        try {
            is = getAssets().open(fileName);
            int len = is.available();
            File file = new File(getFilesDir().getAbsolutePath() + File.separator + fileName);
            fos = new FileOutputStream(file.getPath());
            byte buf[] = new byte[64];
            int temp = 0;
            while ((temp = is.read(buf)) != -1) {
                fos.write(buf, 0, temp);
            }
            fos.flush();
            fos.close();
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
            try {
                fos.close();
                is.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

}
